from constants import *
from math import sin, cos, pi, atan2, sqrt, atan
import copy

class Ship(object):

    def __init__(self,planet):
        
        self.owner = planet.owner
        self.planet = planet
        self.destination = None
        self.x = planet.position[0]
        self.y = planet.position[1]
        self.position = (self.x, self.y)
        self.visible = False
        
        self.status = SHIP_STATUS_BUILDING
        self.buildTimer = SHIP_BUILDING_TIME
        
        self.organics = 0
        self.minerals = 0
        self.population = 0
        self.soldiers = []


    def _distance(self,start,end):
        return sqrt( (end[0] - start[0])**2 + (end[1] - start[1])**2 )
        
        
    def launch(self,destination,population,organics, minerals, soldierNumber): 
        if self.status ==  SHIP_STATUS_BUILDING or self.status ==  SHIP_STATUS_FLYING:
            return "Ship not available"
        
        # hard-coded constant?    
        #if population < 2:
        #    return "You need at least 2 people to fly a ship"
            
        # calculate the needed fuel
        # for now simply consider the distance
        fuelNeeded = int(self._distance(self.planet.position,destination.position))
        if organics < fuelNeeded or self.planet.organics < fuelNeeded:
            return "Not enough fuel (%f needed) " % (fuelNeeded)

        # try to set the cargo
        if population+organics+minerals+soldierNumber > SHIP_CARGO_SPACE :
            return "Not enough cargo space"
            
        # everything ok, launch!
        self._setCargo(population,organics, minerals, soldierNumber)
        
        # burn the needed fuel
        self.organics -= fuelNeeded
        
        self.destination = destination
        return True


    def _setCargo(self,population,organics, minerals, soldierNumber):

        # calculate the right amounts
        organics = min(self.planet.organics,organics)
        minerals = min(self.planet.minerals,minerals)
        population = min(self.planet.population,population)
        soldierNumber = min(len(self.planet.soldiers),soldierNumber)
        
        # load the ship
        for i in range(soldierNumber):
            soldier = self.planet.soldiers[i]
            self.soldiers.append(soldier)

        self.organics = organics
        self.minerals = minerals
        self.population = population

        # remove from planet
        for soldier in self.soldiers:
            self.planet.soldiers.remove(soldier)
            
        self.planet.organics -= organics
        self.planet.minerals -= minerals
        self.planet.population -= population
    
        return True
        
        
    def dropContent(self,planet):
        planet.population += self.population   
        planet.minerals += self.minerals
        planet.organics += self.organics
        planet.soldiers += self.soldiers
        self.population = 0
        self.minerals = 0
        self.organics = 0
        self.soldiers = []
        
        
    def transferOwnership(self,planet):
        # transfer the ship to planet
        self.planet.ships.remove(self) # remove the ship from the original planet list
        planet.ships.append(self)
        self.planet = planet       
        self.destination = None
        self.status = SHIP_STATUS_DOCKED
    
    
    def update(self):
        if self.status == SHIP_STATUS_BUILDING:
            self.buildTimer -= 1    
            if self.buildTimer <= 0:
                self.status = SHIP_STATUS_DOCKED
                
        elif self.status == SHIP_STATUS_DOCKED:
            if self.destination != None:
                self.status = SHIP_STATUS_FLYING
            else:
                self.owner = copy.deepcopy(self.planet.owner)
        elif self.status == SHIP_STATUS_FLYING:

            #update ships position based on the coordinates of start and destination planets
                
            # ship coords
            x0 = float(self.x)
            y0 = float(self.y)
                
            # start planet coords
            x1 = float(self.planet.position[0])
            y1 = float(self.planet.position[1])

            # destination planet coords
            x2 = float(self.destination.position[0])
            y2 = float(self.destination.position[1])

            deltax = (x2 - x1)
            deltay = (y1 - y2)

            angle_rad = atan2(deltay,deltax)
            #angle_deg = angle_rad*180.0/pi
                
            r = float(SHIP_SPEED)
            deltax = r*cos(angle_rad)
            deltay = r*sin(angle_rad)

            # new point
            self.x = x0 + deltax
            self.y = y0 - deltay
            
            self.position = (self.x, self.y)
            
            # if this is an attacking ship, trigger an alarm on the destination planet
            # (if is in radar radius)
            if self.owner != self.destination.owner and self.destination.owner != OWNER_NONE:
                if self._distance((x0,y0),(x2,y2)) < PLANET_RADAR_RADIUS:
                    self.destination.underAttack = True
                    self.visible = True
                else:
                    self.visible = False
            else:
                self.visible = True
                
            # check if the ship reached its destination
            if self._distance((x0,y0),(x2,y2)) < self.destination.size/2:
                #self.planet.ships.remove(self)    
                self.destination._shipArrival(self) 
                #self.planet = self.destination               
                #self.destination = None
                #self.status = SHIP_STATUS_DOCKED
                #print "Moving ship from %.2f %.2f  to %.2f %.2f ; current pos: %.2f %.2f" % (x1,y1,x2,y2,x0,y0)
                
                
       
